
import api_type from "./api_type"
import api_byte from "./api_byte"
export default class O extends api_type{
    private static blob:ArrayBuffer = new ArrayBuffer(2^16); 
    private static view:DataView = new DataView(O.blob);
    private static byte:api_byte = new api_byte(O.blob)
    private static encryptMap:number[] = [0,205,51,152,35,26,83,126,76,100,188,65,108,162,91,94,171,177,53,132,46,220,238,112,28,174,170,245,237,102,189,173,74,99,230,49,151,66,167,226,71,243,6,229,75,34,61,150,128,67,186,1,163,42,192,60,48,37,211,79,113,168,164,198,137,25,219,203,204,33,176,149,121,110,130,111,225,14,97,216,88,153,206,172,252,221,228,145,95,63,240,115,64,253,244,196,185,4,52,7,175,215,194,135,114,41,236,143,124,197,210,78,8,17,160,156,86,13,249,159,139,190,161,84,116,101,179,18,227,241,239,98,147,250,9,193,103,90,70,81,62,136,201,208,96,10,247,21,118,107,169,224,12,104,157,16,181,129,195,134,43,246,209,184,165,182,123,50,109,39,120,69,31,24,146,154,11,214,32,232,217,248,144,142,87,27,178,251,92,148,255,213,19,68,36,106,47,29,44,40,30,187,3,55,223,85,183,105,242,191,72,20,166,180,155,93,200,199,23,138,140,235,207,218,141,54,57,234,133,58,254,158,56,22,117,231,212,127,45,38,202,77,233,73,125,2,222,119,5,82,89,131,122,80,59,15];
    private static decryptMap:number[] = [0,51,245,202,97,248,42,99,112,134,145,176,152,117,77,255,155,113,127,192,211,147,233,218,173,65,5,185,24,197,200,172,178,69,45,4,194,57,239,169,199,105,53,160,198,238,20,196,56,35,167,2,98,18,225,203,232,226,229,254,55,46,140,89,92,11,37,49,193,171,138,40,210,243,32,44,8,241,111,59,253,139,249,6,123,205,116,184,80,250,137,14,188,215,15,88,144,78,131,33,9,125,29,136,153,207,195,149,12,168,73,75,23,60,104,91,124,234,148,247,170,72,252,166,108,244,7,237,48,157,74,251,19,228,159,103,141,64,219,120,220,224,183,107,182,87,174,132,189,71,47,36,3,81,175,214,115,154,231,119,114,122,13,52,62,164,212,38,61,150,26,16,83,31,25,100,70,17,186,126,213,156,165,206,163,96,50,201,10,30,121,209,54,135,102,158,95,109,63,217,216,142,240,67,68,1,82,222,143,162,110,58,236,191,177,101,79,180,223,66,21,85,246,204,151,76,39,128,86,43,34,235,179,242,227,221,106,28,22,130,90,129,208,41,94,27,161,146,181,118,133,187,84,93,230,190];

    //加密
    public static encrypt(blob:ArrayBuffer):ArrayBuffer {
        let _0 = 0;
        let aBytes = new api_byte(blob)
        O.byte.reboot()
        for (let i=0; i<blob.byteLength; i++) {
            let v = aBytes.getUint8(i);
            if (v == 0) {
                //0计数
                _0++;
            } 
            else {
                if (_0 > 0) {
                    _0 -= 1;
                   O.byte.setUint8(0);
                    if (_0 < 128) {
                       O.byte.setUint8(_0);
                    } else if (_0 < 16384) {
                       O.byte.setUint8((_0 >> 8) | 128)
                       O.byte.setUint8(_0 & 0xFF);
                    } else {
                       O.byte.setUint8((_0 >> 16) | 192)
                       O.byte.setUint8((_0 >> 8) & 0xFF)
                       O.byte.setUint8(_0 & 0xFF);
                    }
                    _0 = 0;
                }
               O.byte.setUint8(O.encryptMap[v])
            }
        }
        if (_0 > 0) {
            //写入1个0
            _0 -= 1;
           O.byte.setUint8(0);
            if (_0 < 128) {
                //1个字节记录数量 0     < 2^7
                O.byte.setUint8(_0);
            } else if (_0 < 16384) {
                //2个字节记录数量 1     < 2^14
               O.byte.setUint8((_0 >> 8) | 128);
               O.byte.setUint8(_0 & 0xFF);
            } else {
                //3个字节记录数量 2     < 2^30
               O.byte.setUint8((_0 >> 16) | 192);
               O.byte.setUint8((_0 >> 8) & 0xFF);
               O.byte.setUint8(_0 & 0xFF);
            }
            _0 = 0;
        }
        
        return O.byte.buffer()
    }

    //解密
    public static decrypt(blob:ArrayBuffer):ArrayBuffer {
        //赋值数据
        let aBytes = new api_byte(blob)
        O.byte.reboot()
        //是否零值
        let preIsZero = false;
        let i = 0
        while (i < blob.byteLength) {
            //获取当前值
            let v = aBytes.getUint8(i++);
            if (preIsZero) {
                let _0 = 0;
                if (v < 128) {
                    _0 = v;
                }else if (v < 192) {
                    let v1 = v & 0x3F;
                    let v2 = aBytes.getUint8(i++);
                    _0 = (v1 << 8) | v2;
                }else {
                    let v1 = v & 0x1F;
                    let v2 = aBytes.getUint8(i++);
                    let v3 = aBytes.getUint8(i++);
                    _0 = (v1 << 16) | (v2 << 8) | v3;
                }
                //填充0值
                for (let j=0; j<_0; j++) {
                   O.byte.setUint8(0);
                }
                //0值处理完成
                preIsZero = false;
            }else{
                if (v == 0) {
                    preIsZero = true;
                }
               O.byte.setUint8(O.decryptMap[v]);
            }
        }
        return O.byte.buffer()
    }

}
